#include <i386/stdlib.h>
#include <i386/string.h>
#include <i386/limits.h>
#include <i386/float.h>
#include <ctype.h>
#include <math.h>
#include "sprintf.h"

unsigned ecvt(double v, char *buffer, int width, int prec, int flag) {
	register int len=0;
	long int exponent, abs_exponent;
	
	// inf / NaN
	if (isspecial(v, buffer)) {
		return strlen(buffer);
	}
	
	// check for negative value and add optional + sign
	if (v < 0) {
		*buffer++ = '-';
		v = -v;
		len++;
	} else if (flag & ADD_PLUS) {
		*buffer++ = '+';
		len++;
	}
	
	// zero check
	if (v < DBL_MIN) {
		*buffer++ = '0';
		*buffer = 0;
		return 1;
	}
	// exponent
	if (v < 1) {
		exponent = 0;
		while (v < 1.0) {
		    v *= 10.0;
		    exponent--;
		}
	} else {
		exponent = 0;
		while (v >= 10.0) {
		    v /= 10.0;
		    exponent++;
		}
	}
	
	abs_exponent = abs(exponent);
	
	if (abs_exponent > 99) {
		width -= 3;
	} else if (abs_exponent > 9) {
		width -= 2;
	} else if (exponent > 0) {
		width -= 1;
	}
	
	// now the number is IP in range [0,1]
	// convert this in fixed point format
	len += fcvt(v, buffer, width, prec, flag | RESPECT_WIDTH);
	
	// convert the exponent
	if (exponent == 0) {
		return len;
	}
	
	buffer += len;
	*buffer++ = 'e';
	len += dcvt(exponent, buffer, 10, exponent/10 + 2, ADD_PLUS) + 1;
	
	return len;
}
